package com.aliyun.flashsale.portal.service.impl;

import java.util.concurrent.TimeUnit;

import com.aliyun.commons.model.Result;
import com.aliyun.flashsale.client.model.FlashSaleProductDTO;
import com.aliyun.flashsale.client.service.FlashSaleProductService;
import com.aliyun.flashsale.portal.model.ProductInfoDTO;
import com.aliyun.flashsale.portal.service.ProductQueryService;
import com.aliyun.inventory.client.model.InventoryDTO;
import com.aliyun.inventory.client.service.InventoryService;
import com.aliyun.product.client.constants.ProductStatus;
import com.aliyun.product.client.model.ProductDTO;
import com.aliyun.product.client.service.ProductService;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

/**
 * 商品查询服务实现
 *
 * 
 * @date 2024/11/27
 */
@Service
public class ProductQueryServiceImpl implements ProductQueryService {

    @DubboReference
    private ProductService productService;
    @DubboReference
    private FlashSaleProductService flashSaleProductService;
    @DubboReference
    private InventoryService inventoryService;

    /**
     * 商品+库存本地缓存，用于缓冲对其它系统的调用
     */
    private final LoadingCache<Long, ProductInfoDTO> flashSaleProductCache = Caffeine.newBuilder().refreshAfterWrite(1,
        TimeUnit.SECONDS).expireAfterWrite(2, TimeUnit.SECONDS).maximumSize(10000).build(this::fetchFlashSaleProduct);

    @Override
    public ProductInfoDTO getProductInfo(long flashSaleProductId) {
        // 取商品信息
        ProductInfoDTO infoDTO = flashSaleProductCache.get(flashSaleProductId);
        if (infoDTO == null) {
            throw new RuntimeException("商品信息不存在");
        }
        return infoDTO;
    }

    @Override
    public ProductInfoDTO getProductAndUserPurchaseInfo(long flashSaleProductId, long userId) {
        ProductInfoDTO infoDTO = getProductInfo(flashSaleProductId);
        // 取用户已购数量
        Result<Integer> getUserPurchasedResult = inventoryService.getUserPurchasedQuantity(infoDTO.getProductId(),
            userId);
        if (!getUserPurchasedResult.isSuccess() || getUserPurchasedResult.getData() == null) {
            throw new RuntimeException("获取用户已购数量失败");
        }
        infoDTO.setUserPurchased(getUserPurchasedResult.getData());
        return infoDTO;
    }

    /**
     * 获取商品信息 DTO
     *
     * @param flashSaleProductId 商品 ID
     * @return {@link ProductInfoDTO }
     */
    private ProductInfoDTO fetchFlashSaleProduct(Long flashSaleProductId) {
        // 取秒杀商品
        Result<FlashSaleProductDTO> getFlashSaleProductResult = flashSaleProductService.getFlashSaleProduct(
            flashSaleProductId);
        if (!getFlashSaleProductResult.isSuccess() || getFlashSaleProductResult.getData() == null) {
            throw new RuntimeException("获取秒杀商品信息失败");
        }
        // 取商品
        Long productId = getFlashSaleProductResult.getData().getProductId();
        Result<ProductDTO> getProductResult = productService.getProduct(productId);
        if (!getProductResult.isSuccess() || getProductResult.getData() == null) {
            throw new RuntimeException("获取商品信息失败");
        }
        // 取库存
        Result<InventoryDTO> getInventoryResult = inventoryService.getInventory(productId);
        if (!getInventoryResult.isSuccess() || getInventoryResult.getData() == null) {
            throw new RuntimeException("获取库存信息失败");
        }
        // 取剩余库存
        Result<Integer> getRemainQuantityResult = inventoryService.getRemainQuantity(productId);
        if (!getRemainQuantityResult.isSuccess()) {
            throw new RuntimeException("获取剩余库存信息失败");
        }
        ProductInfoDTO dto = toProductInfoDTO(getProductResult.getData());
        dto.setFlashSaleProductId(flashSaleProductId);
        dto.setStartTime(getFlashSaleProductResult.getData().getStartTime());
        dto.setEndTime(getFlashSaleProductResult.getData().getEndTime());
        dto.setFlashSalePrice(getFlashSaleProductResult.getData().getFlashSalePrice());
        dto.setRemainQuantity(getRemainQuantityResult.getData());
        dto.setTotalQuantity(getInventoryResult.getData().getTotalQuantity());
        dto.setMaxPurchasePerUser(getInventoryResult.getData().getMaxPurchasePerUser());
        return dto;
    }

    /**
     * 转换 DTO
     *
     * @param productDTO 商品 DTO
     * @return {@link ProductInfoDTO }
     */
    private ProductInfoDTO toProductInfoDTO(ProductDTO productDTO) {
        ProductInfoDTO productInfoDTO = new ProductInfoDTO();
        productInfoDTO.setProductId(productDTO.getId());
        productInfoDTO.setTitle(productDTO.getTitle());
        productInfoDTO.setDescription(productDTO.getDescription());
        productInfoDTO.setPic(productDTO.getPic());
        productInfoDTO.setOriginalPrice(productDTO.getOriginalPrice());
        if (ProductStatus.OFFLINE.getValue() == productDTO.getStatus()) {
            productInfoDTO.setStatus(ProductInfoDTO.OFFLINE);
        } else if (ProductStatus.ONLINE.getValue() == productDTO.getStatus()) {
            productInfoDTO.setStatus(ProductInfoDTO.ONLINE);
        } else {
            throw new RuntimeException("商品状态异常");
        }
        return productInfoDTO;
    }
}
